/*
 *  Copyright 2012 yura.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */

/*
 * CopyTemplateScrean.java
 *
 * Created on 17.09.2012, 20:44:40
 */

package org.opu.odg.m_ui;

import java.awt.HeadlessException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ResourceBundle;
import javax.swing.JFileChooser;
import org.apache.commons.io.IOUtils;
import org.opu.odg.dg.DocumentGeneraionService;
import org.opu.odg.dg.logicbeans.ArchiveFileTemplateForDG;
import org.opu.odg.dg.logicbeans.ArchiveFileTemplateForDG.ChangeableEntryDeterminator;
import org.opu.odg.dg.logicbeans.ArchiveFileTemplateForDG.DirectFileNamesEntryDeterminator;
import org.opu.odg.dg.logicbeans.ArchiveFileTemplateForDG.XpathEntryDeterminator;
import org.opu.odg.dg.logicbeans.SingleFileTemplateForDG;
import org.opu.odg.dg.logicbeans.Template;
import org.opu.odg.dg.logicbeans.TemplateFile;
import org.opu.odg.dg.logicbeans.TemplateMetaInf;
import org.opu.odg.dg.logicbeans.TemplateMetaInf.Type;
import org.opu.odg.dg.util.ObjectHolder;
import org.opu.odg.dg.xml.ContentMapping.ContentEntry;
import org.opu.odg.m_ui.tmp.TemplateRepositoryImpl;
import org.opu.odg.m_ui.util.UIUtil;

/**
 *
 * @author yura
 */
public class CopyTemplateScrean extends javax.swing.JDialog {

    private ResourceBundle bundle = ResourceBundle.getBundle("org.opu.odg.m_ui.Bundle");


    private DocumentGeneraionService generaionService;
    private TemplateRepositoryImpl templateRepository;

    private Template editingTemplate;

    public CopyTemplateScrean(java.awt.Frame parent, boolean modal, 
            TemplateRepositoryImpl templateRepository,
            DocumentGeneraionService generaionService, Template editingTemplate,
            String name) throws IOException {
        super(parent, modal);
        this.editingTemplate = editingTemplate;
        this.templateRepository = templateRepository;
        this.generaionService = generaionService;
        TemplateMetaInf metaInf = editingTemplate.getMetaInf();
        editingTemplate.setId(null);
        initComponents();
        nameFiled.setText(name);
        reset();
        setLocationRelativeTo(null);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        topPanel = new javax.swing.JPanel();
        templateNameLbl = new javax.swing.JLabel();
        nameFiled = new javax.swing.JTextField();
        existingBilletLbl = new javax.swing.JLabel();
        billetList = new javax.swing.JComboBox();
        centerPanel = new javax.swing.JPanel();
        fileTypeLbl = new javax.swing.JLabel();
        fileType = new javax.swing.JComboBox();
        entryModeLbl = new javax.swing.JLabel();
        entryModelsList = new javax.swing.JComboBox();
        entryDetermScrollPane = new javax.swing.JScrollPane();
        entryDetermTextAr = new javax.swing.JTextArea();
        bottomPanel = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        fileLbl = new javax.swing.JLabel();
        fileNameField = new javax.swing.JTextField();
        openFileBtn = new javax.swing.JButton();
        jPanel3 = new javax.swing.JPanel();
        cancelBtn = new javax.swing.JButton();
        saveBtn = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle(bundle.getString("template.copy.title")); // NOI18N

        templateNameLbl.setText(bundle.getString("template.new.name")); // NOI18N

        existingBilletLbl.setText(bundle.getString("template.new.billet")); // NOI18N

        billetList.setModel(new javax.swing.DefaultComboBoxModel(new String[] { bundle.getString("billetList.docx"), bundle.getString("billetList.odt"), bundle.getString("billetList.xml"), bundle.getString("billetList.custom")}));
        billetList.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                billetListActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout topPanelLayout = new javax.swing.GroupLayout(topPanel);
        topPanel.setLayout(topPanelLayout);
        topPanelLayout.setHorizontalGroup(
            topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(topPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(templateNameLbl)
                    .addComponent(existingBilletLbl))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(billetList, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(nameFiled, javax.swing.GroupLayout.DEFAULT_SIZE, 327, Short.MAX_VALUE))
                .addContainerGap(85, Short.MAX_VALUE))
        );
        topPanelLayout.setVerticalGroup(
            topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(topPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(templateNameLbl)
                    .addComponent(nameFiled, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(existingBilletLbl)
                    .addComponent(billetList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(43, Short.MAX_VALUE))
        );

        getContentPane().add(topPanel, java.awt.BorderLayout.PAGE_START);

        fileTypeLbl.setText(bundle.getString("template.new.type")); // NOI18N

        fileType.setModel(new javax.swing.DefaultComboBoxModel(new String[] {bundle.getString("fileType.single"), bundle.getString("fileType.archive")}));
        fileType.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                fileTypeActionPerformed(evt);
            }
        });

        entryModeLbl.setText(bundle.getString("template.new.entryDeterminationModel")); // NOI18N

        entryModelsList.setModel(new javax.swing.DefaultComboBoxModel(new String[] {bundle.getString("entryModels.fname"), bundle.getString("entryModels.xpath")}));
        entryModelsList.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                entryModelsListActionPerformed(evt);
            }
        });

        entryDetermScrollPane.setBorder(javax.swing.BorderFactory.createTitledBorder(bundle.getString("template.new.entryDeterminator"))); // NOI18N

        entryDetermTextAr.setColumns(20);
        entryDetermTextAr.setRows(5);
        entryDetermScrollPane.setViewportView(entryDetermTextAr);

        javax.swing.GroupLayout centerPanelLayout = new javax.swing.GroupLayout(centerPanel);
        centerPanel.setLayout(centerPanelLayout);
        centerPanelLayout.setHorizontalGroup(
            centerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(centerPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(centerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(entryDetermScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 509, Short.MAX_VALUE)
                    .addGroup(centerPanelLayout.createSequentialGroup()
                        .addGroup(centerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(entryModeLbl, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(fileTypeLbl, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addGap(41, 41, 41)
                        .addGroup(centerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(fileType, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(entryModelsList, 0, 328, Short.MAX_VALUE))))
                .addContainerGap())
        );
        centerPanelLayout.setVerticalGroup(
            centerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(centerPanelLayout.createSequentialGroup()
                .addGroup(centerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(fileTypeLbl)
                    .addComponent(fileType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(centerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(entryModeLbl)
                    .addComponent(entryModelsList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(entryDetermScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 91, Short.MAX_VALUE)
                .addContainerGap())
        );

        getContentPane().add(centerPanel, java.awt.BorderLayout.CENTER);

        bottomPanel.setLayout(new java.awt.BorderLayout());

        jPanel2.setPreferredSize(new java.awt.Dimension(528, 48));

        fileLbl.setText(bundle.getString("template.new.file")); // NOI18N

        fileNameField.setEditable(false);

        openFileBtn.setText(bundle.getString("template.new.open")); // NOI18N
        openFileBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openFileBtnActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(fileLbl)
                .addGap(97, 97, 97)
                .addComponent(fileNameField, javax.swing.GroupLayout.DEFAULT_SIZE, 342, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(openFileBtn)
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(fileLbl)
                    .addComponent(fileNameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(openFileBtn))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        bottomPanel.add(jPanel2, java.awt.BorderLayout.CENTER);

        cancelBtn.setText(bundle.getString("cancel")); // NOI18N
        cancelBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelBtnActionPerformed(evt);
            }
        });
        jPanel3.add(cancelBtn);

        saveBtn.setText(bundle.getString("Save")); // NOI18N
        saveBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveBtnActionPerformed(evt);
            }
        });
        jPanel3.add(saveBtn);

        bottomPanel.add(jPanel3, java.awt.BorderLayout.PAGE_END);

        getContentPane().add(bottomPanel, java.awt.BorderLayout.PAGE_END);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void billetListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_billetListActionPerformed
        reset();
}//GEN-LAST:event_billetListActionPerformed

    private void fileTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileTypeActionPerformed
        reset();
}//GEN-LAST:event_fileTypeActionPerformed

    private void entryModelsListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_entryModelsListActionPerformed
        reset();
}//GEN-LAST:event_entryModelsListActionPerformed

    private void openFileBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openFileBtnActionPerformed
        JFileChooser fch = new JFileChooser();
        fch.setDialogType(JFileChooser.OPEN_DIALOG);
        fch.setFileSelectionMode(JFileChooser.FILES_ONLY);
        int returnVal = fch.showOpenDialog(this);

        if (returnVal == JFileChooser.APPROVE_OPTION) {

            File file = fch.getSelectedFile();
            FileInputStream is = null;
            try {
                ObjectHolder<TemplateFile> oh = new ObjectHolder<TemplateFile>();
                TemplateMetaInf templateMetaInf = getTemplateMetaInf(oh);
                templateMetaInf.setContents(editingTemplate.getMetaInf().getContents());
                editingTemplate.setTemplateMetaInf(templateMetaInf);
                editingTemplate.setTemplateFile(oh.getObject());

                editingTemplate.getTemplateFile().load(is = new FileInputStream(file));
                fileNameField.setText(file.getAbsolutePath());
            } catch (Exception ex) {
                showError(ex);
            } finally {
                IOUtils.closeQuietly(is);
                reset();
            }
        }
}//GEN-LAST:event_openFileBtnActionPerformed

    private void cancelBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelBtnActionPerformed
        dispose();
}//GEN-LAST:event_cancelBtnActionPerformed

    private void saveBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveBtnActionPerformed
        try {
            List<ContentEntry> mappedEntry = new ArrayList<ContentEntry>();
            List<String> globalVars = new ArrayList<String>();
            generaionService.validate(editingTemplate, globalVars, mappedEntry);
            templateRepository.saveOrUpdate(editingTemplate, nameFiled.getText());

            dispose();
        } catch(Exception ex) {
            showError(ex);
        }

    }//GEN-LAST:event_saveBtnActionPerformed

    
    private void hideAll() {
        fileTypeLbl.setVisible(false);
        entryDetermScrollPane.setVisible(false);
        entryDetermTextAr.setVisible(false);
        fileType.setVisible(false);
        entryModeLbl.setVisible(false);
        entryModelsList.setVisible(false);
    }

    private void reset() {
        hideAll();

        if (billetList.getSelectedIndex() == 3) {
            // it's custom file
            fileTypeLbl.setVisible(true);
            fileType.setVisible(true);

            if (fileType.getSelectedIndex() == 1) {
                // it's custom archive
                entryModeLbl.setVisible(true);
                entryDetermScrollPane.setVisible(true);
                entryDetermTextAr.setVisible(true);
                entryModelsList.setVisible(true);
            }
        }

        topPanel.revalidate();
        centerPanel.revalidate();
        bottomPanel.revalidate();
        pack();
    }

    private TemplateMetaInf getTemplateMetaInf(ObjectHolder<TemplateFile> tfg) throws IOException {
        //"Docx", "Odt", "Xml", "Custom"
        switch (billetList.getSelectedIndex()) {
            case 0:
                return setMetaInfToTemplate(TemplateMetaInf.getDocxBillet(), tfg);
            case 1:
                return setMetaInfToTemplate(TemplateMetaInf.getOdtBillet(), tfg);
            case 2:
                tfg.setObject(new SingleFileTemplateForDG());
                return TemplateMetaInf.getXmlBillet();
            case 3:
                Type fTp = fileType.getSelectedIndex() == 0 ? 
                        Type.SingleFile : Type.ArchiveFile;
                ChangeableEntryDeterminator ced = null;
                if (fTp == TemplateMetaInf.Type.ArchiveFile) {
                    String[] split = entryDetermTextAr.getText().split("\\r?\\n");
                    //"File names in archive", "Xpath expressions to get file names"
                    if (entryModelsList.getSelectedIndex() == 0) {
                        if (split == null || split.length < 1) {
                            exception("Entry determination expect 1 row (at least).");
                        }
                        ced = new DirectFileNamesEntryDeterminator(Arrays.asList(split));
                    } else {
                        if (split == null || split.length < 2) {
                            exception("Entry determination expect 2 row (at least)");
                        }
                        String[] s = new String[split.length - 1];
                        System.arraycopy(split, 1, s, 0, s.length);
                        ced = new XpathEntryDeterminator(split[0], Arrays.asList(s));
                    }
                } else {
                    tfg.setObject(new SingleFileTemplateForDG());
                }

                TemplateMetaInf mi = new TemplateMetaInf(fTp, ced, null);

                if (fTp == TemplateMetaInf.Type.ArchiveFile) {
                    tfg.setObject(new ArchiveFileTemplateForDG(ced));
                }

                return mi;
            default:
                throw new IllegalArgumentException("billetList#getSelectedIndex");
        }
    }

    private TemplateMetaInf setMetaInfToTemplate(TemplateMetaInf mi, ObjectHolder<TemplateFile> tfg) {
        tfg.setObject(new ArchiveFileTemplateForDG(mi.getEntryDeterminator()));
        return mi;
    }

    private void exception(String str) {
        throw new IllegalArgumentException(str);
    }

    protected void showError(Exception ex) throws HeadlessException {
        ex.printStackTrace(System.out);
        UIUtil.niceEx(ex, getTitle(), "");
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    /** Combo box that store type of teplate: docx, odt, ...*/
    private javax.swing.JComboBox billetList;
    private javax.swing.JPanel bottomPanel;
    private javax.swing.JButton cancelBtn;
    private javax.swing.JPanel centerPanel;
    private javax.swing.JScrollPane entryDetermScrollPane;
    private javax.swing.JTextArea entryDetermTextAr;
    private javax.swing.JLabel entryModeLbl;
    private javax.swing.JComboBox entryModelsList;
    private javax.swing.JLabel existingBilletLbl;
    private javax.swing.JLabel fileLbl;
    private javax.swing.JTextField fileNameField;
    private javax.swing.JComboBox fileType;
    private javax.swing.JLabel fileTypeLbl;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JTextField nameFiled;
    private javax.swing.JButton openFileBtn;
    private javax.swing.JButton saveBtn;
    private javax.swing.JLabel templateNameLbl;
    private javax.swing.JPanel topPanel;
    // End of variables declaration//GEN-END:variables

}
